import numpy as np


# save activations and derivatives
# implement backpropagation
# implement gradient descent
# implement train
# train net with some dummy dataset
# make some predictions


# multi layer perception
class MLP:


    def __init__(self, num_inputs=3, num_hidden=[3, 5], num_outputs=2):

        self.num_inputs = num_inputs
        self.num_hidden = num_hidden
        self.num_outputs = num_outputs

        layers = [self.num_inputs] + self.num_hidden + [self.num_outputs]

        # initiate random weights
        weights = []
        for i in range(len(layers) - 1):
            w = np.random.rand(layers[i], layers[i + 1])
            weights.append(w)
        self.weights = weights

        activations = []
        for i in range(len(layers)):
            a = np.zeros(layers[i])
            activations.append(a)
        self.activations = activations
        

    def forward_propagate(self, inputs):

        activations = inputs

        for w in self.weights:
            # calcute net inputs
            net_inputs = np.dot(activations, w)

            # calcute the activations
            activations = self._sigmoid(net_inputs)

        return activations
        
        
    def _sigmoid(self, x):
        return 1 / (1 + np.exp(-x))


if __name__ == "__main__":

    # create an MLP
    mlp = MLP()

    # create some inputs
    inputs = np.random.rand(mlp.num_inputs)

    # perform forward prop
    outputs = mlp.forward_propagate(inputs)

    # print results
    print("The network input is: {}".format(inputs))
    print("The network output is: {}".format(outputs))
